using System;
using System.Collections.Generic;
using System.Text;
using FreeLancer.HRB.Domains;
using FreeLancer.HRB.Services;

namespace FreeLancer.HRB.Core
{
  /// <summary>
  /// Categories are a way to organize posts. 
  /// A post can be in multiple categories.
  /// </summary>
  [Serializable]
  public class Category : IComparable<Category>
  {
    #region Properties

    private CategoriesService _categoryService = GlobalCache.CategoriesService;
    private Categories _data;

    /// <summary>
    /// Data of category.
    /// </summary>
    public Categories Data
    {
      get { return _data; }
    }

    /// <summary>
    /// Gets the full title with Parent names included
    /// </summary>
    public string CompleteTitle()
    {
      if (_data.ParentId == null)
        return _data.CategoryName;
      else
      {
        Categories categoryDomain = _categoryService.GetByCategoryIdLanguageId((Guid)_data.ParentId, 
            _data.LanguageId);
        Category category = new Category(categoryDomain);
        string temp = category.CompleteTitle() + " - " + _data.CategoryName;

        return temp;
      }
    }

    /// <summary>
    /// Gets the Category title.
    /// </summary>
    public string Title
    {
      get { return _data.CategoryName; }
    }

    /// <summary>
    /// Gets Category Id
    /// </summary>
    public Guid Id
    {
      get { return _data.CategoryId; }
    }

    private static object _syncRoot = new object();
    private static List<Category> _categories;
    /// <summary>
    /// A sorted collection of all posts in the blog.
    /// Sorted by date.
    /// </summary>
    public static List<Category> Categories
    {
      get
      {
        if (_categories == null)
        {
          lock (_syncRoot)
          {
            if (_categories == null)
            {
              _categories = FillCategories();
              _categories.TrimExcess();
              _categories.Sort();
            }
          }
        }

        return _categories;
      }
    }

    /// <summary>
    /// A relative-to-the-site-root path to the post.
    /// Only for in-site use.
    /// </summary>
    public string RelativeLink
    {
      get
      {
        string title = Utils.RemoveIllegalCharacters(_data.CategoryName) + WebAppSettings.Instance.FileExtension;
        return Utils.RelativeWebRoot + "category/" + title;
      }
    }

    #endregion

    #region Constructor

    /// <summary>
    /// Constructor.
    /// </summary>
    /// <param name="data">Data of category.</param>
    public Category(Categories data)
    {
      _data = data;
    }

    #endregion

    #region Override methods

    /// <summary>
    /// Returns a <see cref="T:System.String"></see> that represents the current <see cref="T:System.Object"></see>.
    /// </summary>
    /// <returns>
    /// A <see cref="T:System.String"></see> that represents the current <see cref="T:System.Object"></see>.
    /// </returns>
    public override string ToString()
    {
      return CompleteTitle();
    }

    #endregion

    #region IComparable<Category> Members

    /// <summary>
    /// Compares the current object with another object of the same type.
    /// </summary>
    /// <param name="other">An object to compare with this object.</param>
    /// <returns>
    /// A 32-bit signed integer that indicates the relative order of the objects being compared. 
    /// The return value has the following meanings: Value Meaning Less than zero This object is 
    /// less than the other parameter.Zero This object is equal to other. Greater than zero This object is greater than other.
    /// </returns>
    public int CompareTo(Category other)
    {
      return this.CompleteTitle().CompareTo(other.CompleteTitle());
    }

    #endregion

    #region Helpers

    private static List<Category> FillCategories()
    {
      List<Category> categories = new List<Category>();
      CategoriesService service = GlobalCache.CategoriesService;

      TList<FreeLancer.HRB.Domains.Categories> categoryDomains = service.GetAll();
      foreach (Categories categoryDomain in categoryDomains)
      {
        categories.Add(new Category(categoryDomain));
      }

      return categories;
    }

    #endregion
  }
}
